/**
 * @file app_main.c
 * @brief ESP32项目主程序入口文件
 * 
 * 本文件包含系统初始化流程、任务创建和主要应用逻辑。
 * 根据用户配置自动初始化GPIO、WiFi、MQTT等模块。
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"

// 用户配置头文件
#include "user_config.h"
#include "user_gpio.h"
#include "user_wifi.h"
#include "user_mqtt.h"

// 工具组件
#include "log_utils.h"
#include "mem_utils.h"

// 组件头文件
#include "dht11.h"

// OTA相关头文件（如果启用OTA功能）
#if defined(CONFIG_ENABLE_OTA)
#include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
#endif

static const char *TAG = "app_main";

// 任务句柄
static TaskHandle_t dht11_task_handle = NULL;

// 函数声明
static void dht11_task(void *pvParameters);
static void initialize_nvs(void);

/**
 * @brief 应用程序主入口点
 * 
 * 执行系统初始化流程，包括NV存储初始化、GPIO配置、WiFi连接和MQTT初始化。
 */
void app_main(void)
{
    // 初始化日志系统
    log_utils_init();
    ESP_LOGI(TAG, "ESP32项目启动");
    
    // 初始化NV存储
    initialize_nvs();
    
    // 初始化GPIO
    ESP_LOGI(TAG, "初始化GPIO");
    user_gpio_init();
    
    // 初始化LED（如果配置了LED引脚）
#if defined(CONFIG_LED_GPIO)
    user_gpio_led_init();
#endif

    // 初始化WiFi
    ESP_LOGI(TAG, "初始化WiFi");
    user_wifi_init();
    
    // 等待WiFi连接成功
    if (user_wifi_wait_for_connection(portMAX_DELAY)) {
        ESP_LOGI(TAG, "WiFi连接成功");
        
        // 初始化MQTT（如果启用MQTT）
#if defined(CONFIG_ENABLE_MQTT)
        ESP_LOGI(TAG, "初始化MQTT");
        user_mqtt_init();
#endif
        
        // 初始化OTA服务（如果启用OTA）
#if defined(CONFIG_ENABLE_OTA)
        ESP_LOGI(TAG, "初始化OTA服务");
        // OTA初始化在需要时调用
#endif
    } else {
        ESP_LOGE(TAG, "WiFi连接失败");
    }
    
    // 创建DHT11传感器任务（如果配置了DHT11引脚）
#if defined(CONFIG_DHT11_GPIO)
    ESP_LOGI(TAG, "创建DHT11任务");
    BaseType_t result = xTaskCreate(
        dht11_task,
        "dht11_task",
        CONFIG_DHT11_TASK_STACK_SIZE,
        NULL,
        CONFIG_DHT11_TASK_PRIORITY,
        &dht11_task_handle
    );
    
    if (result != pdPASS) {
        ESP_LOGE(TAG, "创建DHT11任务失败");
    }
#endif

    ESP_LOGI(TAG, "主程序初始化完成");
}

/**
 * @brief 初始化NV存储
 * 
 * 初始化NVS Flash存储，用于存储WiFi配置等持久化数据。
 */
static void initialize_nvs(void)
{
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        // NVS分区需要擦除
        ESP_LOGW(TAG, "NVS需要擦除，正在执行擦除操作");
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);
    ESP_LOGI(TAG, "NVS初始化完成");
}

/**
 * @brief DHT11传感器任务
 * 
 * 定期读取DHT11传感器数据并处理。
 * 
 * @param pvParameters 任务参数（未使用）
 */
static void dht11_task(void *pvParameters)
{
    dht11_data_t dht11_data;
    ESP_LOGI(TAG, "DHT11任务启动");
    
    while (1) {
        // 读取DHT11数据
        esp_err_t result = dht11_read_data(&dht11_data);
        if (result == ESP_OK) {
            ESP_LOGI(TAG, "DHT11数据 - 温度: %.1f°C, 湿度: %.1f%%", 
                     dht11_data.temperature, dht11_data.humidity);
            
            // 如果启用MQTT，发送数据
#if defined(CONFIG_ENABLE_MQTT)
            if (user_mqtt_is_connected()) {
                char payload[100];
                snprintf(payload, sizeof(payload), 
                         "{\"temperature\":%.1f,\"humidity\":%.1f}", 
                         dht11_data.temperature, dht11_data.humidity);
                user_mqtt_publish(CONFIG_MQTT_TOPIC_DHT11, payload);
            }
#endif
        } else {
            ESP_LOGE(TAG, "DHT11读取失败: %s", esp_err_to_name(result));
        }
        
        // 等待下一次读取
        vTaskDelay(pdMS_TO_TICKS(CONFIG_DHT11_READ_INTERVAL_MS));
    }
}